package org.rescue.analysis.util;

import javax.swing.tree.DefaultMutableTreeNode;

public class GenericMutableTreeNode <WrappedType> extends DefaultMutableTreeNode {
	   private static final long serialVersionUID = 1;
	   
	   public GenericMutableTreeNode(WrappedType userObject) {
	      super(userObject);
	   }
	 
	   public GenericMutableTreeNode( WrappedType userObject
	                                       , boolean allowsChildren ) {
	      super(userObject, allowsChildren);
	   }
	 
	   //cast is indeed unchecked but it is ensured the type can only be WrappedType
	   @SuppressWarnings("unchecked")
	   //overrides Object DefaultMutableTreeNode.getUserObject() because of covariant return types
	   @Override
	   public WrappedType getUserObject() {
	      return (WrappedType)super.getUserObject();
	   }
	 
	   public final void setUserObject(Object userObject) {
	      throw new UnsupportedOperationException("Cannot ensure type safety: " + userObject.getClass().getName());
	   }
	 
	   public void setObject(WrappedType userObject) {
	      super.setUserObject(userObject);
	   }
	 
	   public WrappedType getObject() {
	      return getUserObject();
	   }
	 
	   public static <Wrapped> GenericMutableTreeNode<Wrapped> wrap(Wrapped object) {
	      return new GenericMutableTreeNode<Wrapped>(object);
	   }
	 
	   public static void main(String[] args) {
	      //using static creation method to avoid repeating <String> on the right hand side
	      GenericMutableTreeNode<String> stringNode = GenericMutableTreeNode.wrap("well well");
	      String string = stringNode.getUserObject(); //no cast, yay
	      stringNode.setUserObject(new Thread()); //runtime safety
	      stringNode.setObject("look here"); //compile time safety
	   }
	}
